package distributedbank.server;

import java.io.Serializable;
import java.util.HashMap;

/**
 * Represents an account in a bank's branch. All of the methods in this class
 * must be thread-safe, since accounts are shared across multiple threads.
 */
public class Account implements Serializable {

    private static final long serialVersionUID = 1L;

    // this is a map from branch ID to the latest successful transaction id
    // received from that branch.
    private final HashMap<Integer, Integer> latestTransactionIds = new HashMap<Integer, Integer>();

    public int balance; // balance in cents

    /**
     * Deposits a (possibly negative) amount of cents to the account and returns
     * the resulting account balance (in cents).
     */
    public int deposit(int amount, int transactionId) {

        if (!this.hasSeenTransactionId(transactionId)) {
            int branchId = transactionId % 100;
            latestTransactionIds.put(branchId, transactionId);
            balance += amount;
        }
        // } else { ... } otherwise, we've seen this transaction before, so we
        // don't change the account balance

        return balance;
    }

    public int query(int transactionId) {

        if (!this.hasSeenTransactionId(transactionId)) {
            int branchId = transactionId % 100;
            latestTransactionIds.put(branchId, transactionId);
        }

        return balance; // the account balance in cents
    }

    /**
     * Returns true if the transactionId
     */
    public boolean hasSeenTransactionId(int transactionId) {

        // the last two digits of the transactionId indicate the branch
        // originating the request
        int branchId = transactionId % 100;
        return latestTransactionIds.containsKey(branchId)
                && latestTransactionIds.get(branchId) >= transactionId;
    }
}
